package xiao_jin.fantastic_journey.core.init;

import club.someoneice.cookie.util.ObjectUtil;
import com.google.common.collect.Lists;
import net.minecraft.component.type.FoodComponent;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.BowItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolMaterials;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Rarity;
import net.minecraft.util.UseAction;
import net.minecraft.util.math.MathHelper;
import xiao_jin.fantastic_journey.FantasticJourney;
import xiao_jin.fantastic_journey.core.common.item.*;
import xiao_jin.fantastic_journey.core.common.item.temp.ManaTest;
import xiao_jin.fantastic_journey.core.common.item.sword.BroadswordItem;
import xiao_jin.fantastic_journey.core.common.item.sword.DaggerItem;
import xiao_jin.fantastic_journey.core.common.item.sword.LongswordItem;
import xiao_jin.fantastic_journey.core.common.item.sword.RapierItem;
import xiao_jin.fantastic_journey.util.ModUtil;

import java.util.Arrays;

@SuppressWarnings("unused")
public final class ModItems {
    //  源材料
    public static final Item ACTIVATE_STICK = registerBaseItem("activate_stick");
    public static final Item GEL = registerBaseItem("gel");
    public static final Item GEL_BLUE = registerBaseItem("gel_blue");
    public static final Item ESSENTIAL_LIFE = registerBaseItem("essential_life");
    public static final Item ESSENTIAL_HOLY = registerBaseItem("essential_holy");
    public static final Item ESSENTIAL_HELL = registerBaseItem("essential_hell");
    public static final Item ESSENTIAL_SPEED = registerBaseItem("essential_speed");
    public static final Item ESSENTIAL_SOUL = registerBaseItem("essential_soul");
    public static final Item ESSENTIAL_UMBRA = registerBaseItem("essential_umbra");
    public static final Item ESSENTIAL_EVIL = registerBaseItem("essential_evil");
    public static final Item ESSENTIAL_END = registerBaseItem("essential_end");
    public static final Item CRYSTAL_FRAGMENTS = registerBaseItem("crystal_fragments");
    public static final Item SOUL_FRAGMENTS = registerBaseItem("soul_fragments");
    public static final Item EMERALD_GRANULES = registerBaseItem("emerald_granules");
    public static final Item IMBECILE_SOUL_STONE = registerBaseItem("imbecile_soul_stone");
    public static final Item EXPLOSIVE_STEEL_INGOT = registerBaseItem("explosive_steel_ingot");
    public static final Item EXPLOSIVE_STEEL_PARTICLE = registerBaseItem("explosive_steel_particle");
    public static final Item EXPLOSIVE_STEEL_PIECE = registerBaseItem("explosive_steel_piece");
    public static final Item WIND_CORE = registerBaseItem("wind_core");
    public static final Item BREEZE_INGOT = registerBaseItem("breeze_ingot");
    public static final Item ANCIENT_RECIPES = registerTemplate("ancient_recipes", ModSmithingTemplateItem.createAncientFoodUpgrade(), ModItemGroup.Ingredients);
    public static final Item WARDEN_HEART = registerBaseItem("warden_heart");

    // 食物
    public static final Item ANCIENT_CHOCOLATE = registerItem("ancient_chocolate", createFood(20, 1.0f, true, false, 30f, ModFoodHelper.ANCIENT_CHOCOLATE_EFFECTS), ModItemGroup.Food);
    public static final Item NSCULK_CHOCOLATE = registerItem("nsculk_chocolate", createFood(20, 1.0f, true, false, 15f, ModFoodHelper.NSCULK_CHOCOLATE_EFFECTS), ModItemGroup.Food);

    //  杂项
    public static final Item SANDPAPER = registerItem("sandpaper", new Item(new Item.Settings()), ModItemGroup.Sundries);

    //  贡献者物品
    public static final Item DIAMOND = registerItem("diamond", new Diamond(), ModItemGroup.Contributor);
    public static final Item COLLAR = registerItem("collar", new Collar(), ModItemGroup.Contributor);
    public static final Item LEGACYBUTTON = registerItem("legacy_button", new LegacyButton(new Item.Settings().maxCount(1).rarity(Rarity.EPIC)), ModItemGroup.Contributor);

    //  战斗用品
    // 法器
    public static final Item WAND_APPRENTICE = registerItem("wand_apprentice", new Item(new Item.Settings().maxCount(1)), ModItemGroup.CombatSupplies);
    public static final Item WAND_WOODEN = registerItem("wand_wooden", new Item(new Item.Settings().maxCount(1)), ModItemGroup.CombatSupplies);
    // 近战
    public static final Item DAGGER_WOOD = registerItem("dagger_wood", new DaggerItem(ToolMaterials.WOOD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.WOOD, 1, 1.2F, -2, +0.01f)).maxDamage(29)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_STONE = registerItem("dagger_stone", new DaggerItem(ToolMaterials.STONE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.STONE, 1.5F, 1.2F, -2, +0.01f)).maxDamage(65)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_IRON = registerItem("dagger_iron", new DaggerItem(ToolMaterials.IRON, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.IRON, 0, 1.2F, -2, +0.01f)).maxDamage(125)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_GOLD = registerItem("dagger_gold", new DaggerItem(ToolMaterials.GOLD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.GOLD, 1, 1.2F, -2, +0.01f)).maxDamage(16)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_DIAMOND = registerItem("dagger_diamond", new DaggerItem(ToolMaterials.DIAMOND, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.DIAMOND, -0.5F, 1.2F, -2, +0.01f)).maxDamage(780)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_EMERALD = registerItem("dagger_emerald", new DaggerItem(ModToolMaterials.EMERALD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ModToolMaterials.EMERALD, -0.5F, 1.2F, -2, +0.01f)).maxDamage(800)), ModItemGroup.CombatSupplies);
    public static final Item DAGGER_NETHERITE = registerItem("dagger_netherite", new DaggerItem(ToolMaterials.NETHERITE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.NETHERITE, 1, 1.2F, -2, +0.01f)).maxDamage(1015)), ModItemGroup.CombatSupplies);

    public static final Item LONGSWORD_WOOD = registerItem("longsword_wood", new LongswordItem(ToolMaterials.WOOD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.WOOD, 4, -3.0F, 2.5F, -0.01f)).maxDamage(233)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_STONE = registerItem("longsword_stone", new LongswordItem(ToolMaterials.STONE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.STONE, 4, -3.0F, 2.5F, -0.01f)).maxDamage(521)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_IRON = registerItem("longsword_iron", new LongswordItem(ToolMaterials.IRON, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.IRON, 4, -3.0F, 2.5F, -0.01f)).maxDamage(1000)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_GOLD = registerItem("longsword_gold", new LongswordItem(ToolMaterials.GOLD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.GOLD, 4, -3.0F, 2.5F, -0.01f)).maxDamage(64)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_DIAMOND = registerItem("longsword_diamond", new LongswordItem(ToolMaterials.DIAMOND, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.DIAMOND, 4, -3.0F, 2.5F, -0.01f)).maxDamage(3121)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_EMERALD = registerItem("longsword_emerald", new LongswordItem(ModToolMaterials.EMERALD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ModToolMaterials.EMERALD, 4, -3.0F, 2.5F, -0.01f)).maxDamage(3200)), ModItemGroup.CombatSupplies);
    public static final Item LONGSWORD_NETHERITE = registerItem("longsword_netherite", new LongswordItem(ToolMaterials.NETHERITE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.NETHERITE, 6, -3.0F, 2.5F, -0.01f)).maxDamage(4061)), ModItemGroup.CombatSupplies);

    public static final Item BROADSWORD_WOOD = registerItem("broadsword_wood", new BroadswordItem(ToolMaterials.WOOD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.WOOD, 6, -3.0F, 1, -0.03f)).maxDamage(175)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_STONE = registerItem("broadsword_stone", new BroadswordItem(ToolMaterials.STONE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.STONE, 6, -3.0F, 1, -0.03f)).maxDamage(391)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_IRON = registerItem("broadsword_iron", new BroadswordItem(ToolMaterials.IRON, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.IRON, 6, -3.0F, 1, -0.03f)).maxDamage(1500)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_GOLD = registerItem("broadsword_gold", new BroadswordItem(ToolMaterials.GOLD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.GOLD, 6, -3.0F, 1, -0.03f)).maxDamage(96)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_DIAMOND = registerItem("broadsword_diamond", new BroadswordItem(ToolMaterials.DIAMOND, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.DIAMOND, 6, -3.0F, 1, -0.03f)).maxDamage(4681)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_EMERALD = registerItem("broadsword_emerald", new BroadswordItem(ModToolMaterials.EMERALD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ModToolMaterials.EMERALD, 6, -3.0F, 1, -0.03f)).maxDamage(4800)), ModItemGroup.CombatSupplies);
    public static final Item BROADSWORD_NETHERITE = registerItem("broadsword_netherite", new BroadswordItem(ToolMaterials.NETHERITE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.NETHERITE, 8, -3.0F, 1, -0.03f)).maxDamage(6091)), ModItemGroup.CombatSupplies);

    public static final Item RAPIER_WOOD = registerItem("rapier_wood", new RapierItem(ToolMaterials.WOOD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.WOOD, 3, 1.0F, 0.5F, 0f)).maxDamage(88)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_STONE = registerItem("rapier_stone", new RapierItem(ToolMaterials.STONE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.STONE, 3, 1.0F, 0.5F, 0f)).maxDamage(196)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_IRON = registerItem("rapier_iron", new RapierItem(ToolMaterials.IRON, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.IRON, 3, 1.0F, 0.5F, 0f)).maxDamage(750)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_GOLD = registerItem("rapier_gold", new RapierItem(ToolMaterials.GOLD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.GOLD, 3, 1.0F, 0.5F, 0f)).maxDamage(48)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_DIAMOND = registerItem("rapier_diamond", new RapierItem(ToolMaterials.DIAMOND, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.DIAMOND, 3, 1.0F, 0.5F, 0f)).maxDamage(2341)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_EMERALD = registerItem("rapier_emerald", new RapierItem(ModToolMaterials.EMERALD, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ModToolMaterials.EMERALD, 3, 1.0F, 0.5F, 0f)).maxDamage(2400)), ModItemGroup.CombatSupplies);
    public static final Item RAPIER_NETHERITE = registerItem("rapier_netherite", new RapierItem(ToolMaterials.NETHERITE, new Item.Settings()
            .attributeModifiers(ModSwordItem.createAttributeModifiers(ToolMaterials.NETHERITE, 3, 1.0F, 0.5F, 0f)).maxDamage(3046)), ModItemGroup.CombatSupplies);
    // 远程武器
    public static final Item RESONANCE = registerItem("resonance", new BowItem(new Item.Settings().maxDamage(1000).rarity(Rarity.EPIC)), ModItemGroup.CombatSupplies);
    public static final Item END_BREATHING = registerItem("end_breathing", new EndBreathing(new Item.Settings().maxDamage(1000).rarity(Rarity.EPIC)), ModItemGroup.CombatSupplies);

    //  测试工具
    public static final Item TEST_MANA_TOOL = registerItem("test_mana_tool", new ManaTest(), ModItemGroup.Tools);


    private static Item createFood(int hunger, float saturation, boolean alwaysEat, boolean isDrink, float eatTime, StatusEffectInstance... effects) {
        Item.Settings setting = new Item.Settings();

        FoodComponent.Builder builder = new FoodComponent.Builder();
        builder.nutrition(hunger).saturationModifier(saturation);
        if (alwaysEat) {
            builder.alwaysEdible();
        }
        Arrays.stream(effects).forEach(it -> builder.statusEffect(it, 1.0f));

        return new Item(setting.food(builder.build())) {
            @Override
            public int getMaxUseTime(ItemStack stack, LivingEntity user) {
                return MathHelper.floor(eatTime * 20);
            }

            @Override
            public UseAction getUseAction(ItemStack stack) {
                return isDrink ? UseAction.DRINK : UseAction.EAT;
            }
        };
    }

    private static Item registerBaseItem(String name) {
        return registerItem(name, new Item(new Item.Settings()), ModItemGroup.Ingredients);
    }

    private static Item registerItem(String name, Item item, ModItemGroup group) {
        Registry.register(Registries.ITEM, ModUtil.getIdOfMod(name), item);
        var map = FantasticJourney.ITEM_GROUP_MAP;
        map.put(group, ObjectUtil.objectRun(map.getOrDefault(group, Lists.newArrayList()), it -> {
            it.add(item);
        }));
        return item;
    }

    private static Item registerTemplate(String name, Item item, ModItemGroup group) {
        Registry.register(Registries.ITEM, ModUtil.getIdOfMod(name), item);
        var map = FantasticJourney.ITEM_GROUP_MAP;
        map.put(group, ObjectUtil.objectRun(map.getOrDefault(group, Lists.newArrayList()), it -> {
            it.add(item);
        }));
        return item;
    }

    public static void registerModItem() {
    }
}
